#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
串口工具模块 - 串口通信相关功能
"""

import serial
import glob
import os
from config import SERIAL_PORT_PATTERNS
import time


class SerialManager:
    """串口管理器"""
    
    def __init__(self, port, baudrate):
        self.port = port
        self.baudrate = baudrate
        self.serial_conn = None
    
    def connect(self):
        """连接串口，优化Linux环境"""
        try:
            self.serial_conn = serial.Serial(
                port=self.port,
                baudrate=self.baudrate,
                bytesize=serial.EIGHTBITS,
                parity=serial.PARITY_NONE,
                stopbits=serial.STOPBITS_ONE,
                timeout=3,  # 增加超时时间到3秒，提供更充足的等待时间
                xonxoff=False,
                rtscts=False,
                dsrdtr=False
            )
            
            # Linux下设置更大的缓冲区以适应高速图像传输
            try:
                self.serial_conn.set_buffer_size(rx_size=512000, tx_size=8192)  # 增大接收缓冲区
            except AttributeError:
                # 某些系统可能不支持这个方法
                pass
            
            print(f"已连接到串口 {self.port}，波特率 {self.baudrate}")
            return True
        except serial.SerialException as e:
            print(f"串口连接失败: {e}")
            if "Permission denied" in str(e):
                print("权限错误解决方案:")
                print("1. 添加用户到dialout组: sudo usermod -a -G dialout $USER")
                print("2. 重新登录或重启WSL2")
                print("3. 或临时使用: sudo chmod 666 /dev/ttyUSB*")
            return False
        except Exception as e:
            print(f"串口连接失败: {e}")
            return False
    
    def disconnect(self):
        """断开串口连接"""
        if self.serial_conn and self.serial_conn.is_open:
            self.serial_conn.close()
            print("串口已断开")
    
    def is_connected(self):
        """检查串口是否连接"""
        return self.serial_conn and self.serial_conn.is_open
    
    def send_data(self, data):
        """发送数据到串口"""
        if not self.is_connected():
            return False
        
        try:
            if isinstance(data, str):
                data = data.encode('utf-8')
            self.serial_conn.write(data)
            self.serial_conn.flush()
            return True
        except Exception as e:
            print(f"串口发送数据失败: {e}")
            return False
    
    def read_line(self):
        """从串口读取一行数据"""
        if not self.is_connected():
            return None
        
        try:
            return self.serial_conn.readline().decode('utf-8', errors='ignore').strip()
        except Exception as e:
            print(f"串口读取数据失败: {e}")
            return None
    
    def read_line_timeout(self, timeout=2.0):
        """
        读取一行数据，带超时
        :param timeout: 超时时间（秒）
        :return: 读取到的行数据
        """
        if not self.is_connected():
            return None
        
        start_time = time.time()
        line = b''
        
        while time.time() - start_time < timeout:
            if self.serial_conn.in_waiting > 0:
                char = self.serial_conn.read(1)
                if char == b'\n':
                    return line.decode('utf-8', errors='ignore').strip()
                line += char
        
        return None
    
    def read_bytes(self, size):
        """从串口读取指定字节数的数据"""
        if not self.is_connected():
            return None
        
        try:
            return self.serial_conn.read(size)
        except Exception as e:
            print(f"串口读取数据失败: {e}")
            return None
    
    def flush_input(self):
        """清空输入缓冲区"""
        if self.is_connected():
            try:
                # 新版本pySerial使用reset_input_buffer
                self.serial_conn.reset_input_buffer()
            except AttributeError:
                # 兼容旧版本的flushInput
                self.serial_conn.flushInput()


def list_serial_ports():
    """列出可用的串口设备"""
    available_ports = []
    
    for pattern in SERIAL_PORT_PATTERNS:
        ports = glob.glob(pattern)
        available_ports.extend(ports)
    
    # 过滤出真正可用的端口
    working_ports = []
    for port in available_ports:
        try:
            with serial.Serial(port, timeout=0.1) as ser:
                working_ports.append(port)
        except:
            continue
    
    print("可用的串口设备:")
    for i, port in enumerate(working_ports):
        try:
            # 获取设备信息
            info = f"{port}"
            if os.path.exists(port):
                stat = os.stat(port)
                info += f" (权限: {oct(stat.st_mode)[-3:]})"
            print(f"{i+1}. {info}")
        except:
            print(f"{i+1}. {port}")
    
    return working_ports


def select_serial_port(available_ports):
    """选择串口设备"""
    if not available_ports:
        print("未找到可用的串口设备")
        print("WSL2用户请参考:")
        print("1. 使用 usbipd-win 转发USB设备")
        print("2. 或在Windows运行串口转发服务")
        print("3. 或使用Debug模式进行测试")
        return None
    
    if len(available_ports) == 1:
        selected_port = available_ports[0]
        print(f"自动选择唯一可用串口: {selected_port}")
        return selected_port
    
    try:
        port_index = int(input("请选择串口 (输入数字): ")) - 1
        if 0 <= port_index < len(available_ports):
            return available_ports[port_index]
        else:
            print("无效的选择，使用第一个可用串口")
            return available_ports[0]
    except ValueError:
        print("无效输入，使用第一个可用串口")
        return available_ports[0]


def select_baudrate():
    """选择波特率"""
    from config import AVAILABLE_BAUDRATES
    
    print("\n可用波特率:")
    for i, br in enumerate(AVAILABLE_BAUDRATES):
        print(f"{i+1}. {br}")
    
    try:
        br_index = int(input("请选择波特率 (输入数字，默认3): ")) - 1
        if 0 <= br_index < len(AVAILABLE_BAUDRATES):
            return AVAILABLE_BAUDRATES[br_index]
        else:
            return AVAILABLE_BAUDRATES[-1]  # 默认最高波特率
    except ValueError:
        return AVAILABLE_BAUDRATES[-1]  # 默认最高波特率 